【论文笔记】DICE: Automatic Emulation of DMA Input Channels for Dynamic Firmware Analysis

2021-0712-DICE

DICE: Automatic Emulation of DMA Input Channels for Dynamic Firmware Analysis

作者:Alejandro Mera, Bo Feng, Long Lu, Engin Kirda, William Robertson

单位:Northeastern University

会议:S&P 2021

链接:https://www.longlu.org/publication/dice/dice.pdf

Abstract

目前的针对于固件的动态分析方法存在一个比较大的局限性:无法处理固件中的DMA(Direct Memory Access)操作。从而限制了分析所支持的设备种类以及代码覆盖率。

作者提出了DICE,一种模拟DMA input channel并生成DMA输入的动态分析方法。其核心思想是识别和模拟抽象的DMA input channel,而不是模拟种类繁多的外设及控制器。

作者在针对ARM Cortex-M的P2IM以及针对于MIPS M4K/M-class的PIC32模拟器上实现了DICE。在83个benchmarks上进行测试,检测到了来自5个不同厂商的9种不同的DMA 控制器。对7个fuzz-tested的真实世界的固件进行分析,执行路径比之前的高79倍,并额外发现了5个位置漏洞。

Introduction

为了提高嵌入式系统的安全性,研究人员使用了多种方法:runtime attack mitigation,remote attestation和固件分析。其中固件分析误报率低,不需要修改软硬件,不会在生产设备上引入额外的开销,故固件分析的方法更受青睐。

但一个基本的问题仍然普遍存在:现有的动态分析方法不能支持固件通过DMA从外设中获取输入,当固件从内存中的DMA缓冲区读取数据时,该缓冲区应包含由外设直接写入的数据,但目前的分析或模拟方法却只能将其视为常规的内存读取操作,返回0或无效值。使得固件无法获得任何DMA输入,从而导致代码覆盖率较低、甚至奔溃等问题。

根本原因在于DMA允许外设直接访问内存。固件分析器如果不能完全模拟所有外设或完全理解它们的DMA activities,就无法确定内存中基于DMA的I/O何时何地发生。现有的方案要么将DMA视为out of scope,要么使用非常简单的启发式方法来静态推断出内存中的DMA缓冲区位置。

本文中作者提出了DICE (DMA Input Channel Emulation),可用于动态固件分析器识别和操作基于DMA的外设输入,从而扩展其用于覆盖以来DMA输入的固件代码、状态、漏洞。

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled.png

作者设计DICE用于模拟DMA input channel,当固件内存访问的source或destination为内存中的固定区域时(即DMA内存地址),DICE识别其为DMA input channel。并想分析器发送信号以进行进一步处理。

主要解决了三个挑战:DMA input channel是在执行期间由固件创建或删除的,DICE需要动态识别这些channel,并监控输入事件。嵌入式软硬件的多样性使得通用性的DICE设计更加困难。大量固件都是二进制形式的,没有源代码和调试符号。

Motivation

以某款基于MCU的GPS设备为例,它使用UART从GPS天线接受序列化消息,这些消息通过DMA复制到RAM,然后固件解析消息并计算位置信息,然后通过DMA将其复制到连接到SPI的LCD。如果没有外围设备的支持,这个GPS固件的动态分析无法到达大部分代码,因为固件无法接受任何输入,甚至无法启动设备。最近的一些工作使用不同的方法解决了外围设备依赖的问题,然而它们仅关注使用内存映射I/O的简单外设(2)。依靠手动识别DMA缓冲区或通过手动编写hook替换HAL函数来彻底替换DMA。到目前为止,还没有工作支持使用DMA与固件通信的复杂外设(1)。

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%201.png

Survey on DMA Availability and Usage on MCUs

DMA Availability on MCUs

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%202.png

DMA Usage by Firmware

在Github中收集了1000个与microcontrollers, IoT, and DMA相关的repo,发现920个包含与DMA相关的头文件或代码。数据集中的350个ELF中有88个包含与DMA相关的调试符号。

System Design

DICE的设计目标:硬件独立性、软件兼容性、动态DMA、无需源代码、能够与分析器集成

DMA Input Channels

DMA Input Channels是作者定义的一个抽象概念,可以视为固件与外设通过DMA交换数据的桥梁。output channel的定义类似,传输方向相反(数据通过DMA传输到外设)。source&destination所有可能的组合如表II所示。

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%203.png

每个DMA传输需要三个步骤:

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%204.png

Capturing Stream Configurations

作者发现了DMA流配置遵循一种较为明显的模式:将特定范围内的一些值写入内存中的固定区域。这种模式与在每个DMA流配置中执行的基本操作相呼应,即将源和目标传输指针写入 DMA 控制器寄存器。这些外设寄存器始终映射到MMIO区域(0x40000000–0x5fffffff)。源传输指针的值必须在 0x40000000–0x5fffffff(对于外设 MMIO)、0x20000000-0x20004fff(对于 RAM)或 0x8000000-0x801ffff(对于 Flash)的范围内。

根据经验,固件仅在DMA 流配置时将两个指针/地址值写入两个连续的 MMIO 寄存器。

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%205.png

DICE在监控执行时固件写入内存时判断是否为流配置的pattern,当发现为流配置的pattern时,DICE从中提取出传输指针并判断传输方向。当发现将数据传输到RAM的DMA流配置时,DICE找到其目的地址,并意味着新的DMA input channel建立。

Responding to DMA Data Read

在 DICE 捕获 DMA 流配置并找到目标地址后,它会在目标地址上设置一个access hook。但仍存在两个问题:buffer size未知、DMA input channel会动态终止。

Unknown buffer size: 一个最直观的解决方案是从编译器生成的调试符号中直接提取缓冲区大小。但是DICE采用了一种动态推断的方式,无需调试符号。基于:固件通常在空间中连续读取DMA缓冲区(from the beginning to the end, but not necessarily consecutive in time)。如下图算法所示,其动态的增加DMA缓冲区的估计值。

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%206.png

Dynamic channel terminations:如果无法识别已经关闭的DMA input channel,会导致 DICE 和固件分析错误地将常规内存访问视为 DMA 输入事件,从而影响固件的正常执行。DICE将两种模式视作input channel终止的信号:1、新的DMA流配置与之前的相同,2、固件写入与DMA input channel对应的内存buffer中, 该input channel将被隐式终止。

Evaluation

Intel Core i5-7260U CPU @ 2.20GHz, 8 GB of RAM, and a fresh installation of Ubuntu 18.04 LTS.

Unit Tests on Sample Firmware

Experiment Setup:

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%207.png

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%208.png

True positive and false negative analysis:

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%209.png

Runtime overhead:

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%2010.png

Fuzz-testing Real Firmware

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%2011.png

Fuzzing Statistics:

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%2012.png

Detected New Bugs and Case Study:

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%2013.png

case study Bug #1:

(the correct check should be startAddr >= MODBUS_SLAVE_REGISTERS_NUM)

2021-0712-DICE%20105af14bb31f41cd8b1f654117fb948d/Untitled%2014.png

Conclusion

作者对DMA的使用情况进行了较大规模的调查,显示了DMA在基于MCU的嵌入式设备上的普遍性和多样性。为了解决现有固件动态分析方案,作者设计了DICE,通过集成到现有分析方案,实现与硬件无关的DMA输入模拟。并能够自动化的推断出DMA缓冲区的位置及大小。